/*
 * Flashlib - QB9 common Flash library
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.qb9.flashlib.ui
{
	import flash.display.InteractiveObject;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.ColorTransform;
	
	/**
	 * Add visual and sound effects to buttons (interactive object) on the stage.
	 *
	 * <p>This class can be used to give the same rollover / click effect
	 * to all (or some) buttons in the application.</p>
	 *
	 * <p>The default is a brightening
	 * effect for the roll-over event, and no sound effect.</p>
	 */
	public class ButtonManager
	{
		/**
		 * Function that applies a visual effect when the mouse rolls over the button.
		 * The function should take the button InteractiveObject as its only argument.
		 *
		 * <p>The default effect (<code>null</code>)
		 * is to apply a color transformation.</p>
		 */
		public var rollOverEffect:Function;
		
		/**
		 * Function that applies an effect when the mouse rolls out of the button.
		 * The function should take the button InteractiveObject as its only argument.
		 *
		 * <p>The default effect (<code>null</code>)
		 * is to remove the color transformation.</p>
		 */
		public var rollOutEffect:Function;
		
		/**
		 * Function that will play a sound when the mouse rolls over the button.
		 *
		 * <p>The default (<code>null</code>)
		 * is no sound effect.</p>
		 */
		public var playRollOverSound:Function;
		
		/**
		 * Function that will play a sound when the button is clicked.
		 *
		 * <p>The default (<code>null</code>)
		 * is no sound effect.</p>
		 */
		public var playClickSound:Function;
		
		/**
		 * Create a ButtonManager instance.
		 *
		 * @param rollOverEffect Visual effect used when the mouse rolls over the button.
		 * @param rollOutEffect Visual effect used when the mouse rolls out the button.
		 * @param playRollOverSound Function that will play a sound when the mouse rolls over the button.
		 * @param playClickSound Function that will play a sound when the button is clicked.
		 *
		 * @see ButtonManager.rollOverEffect
		 * @see ButtonManager.rollOutEffect
		 * @see ButtonManager.playRollOverSound
		 * @see ButtonManager.playClickSound
		 */
		public function ButtonManager(rollOverEffect:Function = null, rollOutEffect:Function = null, playRollOverSound:Function = null, playClickSound:Function = null)
		{
			this.rollOverEffect = rollOverEffect;
			this.rollOutEffect = rollOutEffect;
			this.playRollOverSound = playRollOverSound;
			this.playClickSound = playClickSound;
		}

		private function _onRollOver(ev:MouseEvent):void
		{
			if (playRollOverSound != null)
				playRollOverSound();
			
			if (rollOverEffect != null)
			{
				rollOverEffect(ev.currentTarget);				
			}
			else
			{
				InteractiveObject(ev.currentTarget).transform.colorTransform = new ColorTransform(1.2,1.2,1.2);
			}
		}
		
		private function _onRollOut(ev:MouseEvent):void
		{
			if (rollOutEffect != null)
			{
				rollOutEffect(ev.currentTarget);				
				
			}
			else
			{				
				InteractiveObject(ev.currentTarget).transform.colorTransform = new ColorTransform();
			}
		}

		/**
		 * Adds all event listeners to the given button, including visual and sound effects.
		 * 
		 * @param button The InteractiveObject that represents the button in the user interface.
		 * @param onClick Callback function to be called when the button is clicked.
		 */
		public function addButton(button:InteractiveObject, onClick:Function = null):void
		{			
			if (button == null) return;
			if (button is Sprite) Sprite(button).buttonMode = true;
			if (onClick != null)
				button.addEventListener(MouseEvent.CLICK, onClick);
			if (playClickSound != null)
				button.addEventListener(MouseEvent.CLICK, playClickSound);
			button.addEventListener(MouseEvent.ROLL_OVER, _onRollOver, false, 0, true);
			button.addEventListener(MouseEvent.ROLL_OUT, _onRollOut, false, 0, true);
		}
		
		/**
		 * Removes all event listeners to the given button, that had been previously added.
		 * There is no need to use these function unless you specifically want to remove the button functionality,
		 * since all listeners are added using weak references.
		 * 
		 * @param button The InteractiveObject that represents the button in the user interface.
		 * @param onClick Function that was registered as the click callback.
		 */
		public function removeButton(button:InteractiveObject, onClick:Function = null):void
		{						
			if (button is Sprite) Sprite(button).buttonMode = false;
			if (onClick != null)
				button.removeEventListener(MouseEvent.CLICK, onClick);
			if (playClickSound != null)
				button.removeEventListener(MouseEvent.CLICK, playClickSound);
			button.removeEventListener(MouseEvent.ROLL_OVER, _onRollOver);
			button.removeEventListener(MouseEvent.ROLL_OUT, _onRollOut);
		}
	}
}
